
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Text.RegularExpressions;
using System.Text;

namespace Swaf.Messaging
{
    public class BaseMessageResolver : IMessageResolver
    {
        #region IMessageResolver Members

        public virtual string format(string baseMessage, Swaf.Container.INameAddressSupport info)
        {
            if (info == null)
            {
                return baseMessage;
            }

            StringBuilder result = new StringBuilder(baseMessage);
            Regex p = Application.currentApp.resMgr.knownGoodPattern("$({1+ {not-oneof $}})$");

            Object val = null;
            int lastPos = 0;
            Match rc;

            //rc will be the result match of the first instance of $..$
            while ((rc = p.Match(result.ToString(lastPos, result.Length - lastPos))).Success)
            {
                try
                {
                    Group nextMatch = rc.Groups[0];
                    Group nextMatch2 = rc.Groups[1];
                    //rc.Groups[1] is the parm portion of $parm$
                    //rc.Index is the index of the start of $parm$
                    //rc.Groups[1].Index is the start of parm inside of $parm$
                    //val = Application.currentApp.resMgr.resolve(rc.Groups[1].Value);
                    val = info.get(rc.Groups[1].Value);	//Get value for this parameter
                    if (val != null)
                    {
                        result.Remove(lastPos + rc.Index, rc.Length);
                        result.Insert(lastPos + rc.Index, val.ToString());

                        //lastpos += (Before Replacment Last Position) + (Length New String - Length Original String)
                        //lastPos += rc.Index + rc.Length + (val.ToString().Length - nextMatch.Length);
                        lastPos += rc.Index + val.ToString().Length;
                    }
                    else
                    {
                        lastPos += rc.Groups[1].Index; // + rc.Length;
                    }
                }
                catch (Exception e)
                {
                    throw new MessageResolverException("Unable to resolve embedded macros in message.", e);
                }
            }

            return result.ToString();
        }

        #endregion
    }

    [Serializable]
    public class MessageResolverException : BaseException
    {
        public MessageResolverException()
            : base()
        {
        }

        public MessageResolverException(string message)
            : base(message)
        {
        }

        public MessageResolverException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        public MessageResolverException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
            : base(info, context)
        {
        }
    }
}
